﻿using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.DirectoryServices.AccountManagement;

namespace Red.Launcher.ViewModels.Workspaces.Database
{
    public class User : Record
    {
        #region Private Data

        private bool _isAdmin;
        private UserPrincipal _userPrincipal;

        #endregion Private Data

        #region Inherited Properties

        public override Metadata Metadata { get { return METADATA; } }
        public override string Icon { get { return ( IsAdmin ) ? "appbar_user_tie" : "appbar_user"; } }
        public override IEnumerable<object> Values { get { return new List<object>() { Name, IsAdmin }; } }

        #endregion Inherited Properties

        #region Public Properties

        public static Metadata METADATA { get; private set; }

        public bool IsAdmin
        {
            get { return _isAdmin; }
            set
            {
                if ( _isAdmin != value )
                {
                    _isAdmin = value;
                    OnPropertyChanged();
                }
            }
        }

        #endregion Public Properties

        #region Internal Properties

        internal P4Credential DefaultCredential { get; private set; }

        internal UserPrincipal UserPrincipal
        {
            get
            {
                if( _userPrincipal == null )
                {
                    CacheUserPrincipal();
                }

                return _userPrincipal;
            }
        }

        #endregion Internal Properties

        #region C-Tor

        static User()
        {
            METADATA = new Metadata()
            {
                Table = "Users",
                Keys = new List<string>() { "username_win", "admin" },
                CanCopy = true,
                CreateDefault = () => { return new User(); },
                CreateFromDatabaseRow = ( Dictionary<string, object> data ) =>
                {
                    return new User()
                    {
                        Id = (int)data[ "id" ],
                        Name = (string)data[ "username_win" ],
                        IsAdmin = (bool)data[ "admin" ]
                    };
                }
            };

            METADATA.Children.Add( typeof( P4Credential ) );
        }

        public User()
        {
            Children.CollectionChanged += Children_CollectionChanged;
        }

        #endregion C-Tor

        #region Public Methods

        public static User Create( Dictionary<string, object> data, bool watchForChanges )
        {
            User user = (User)METADATA.CreateFromDatabaseRow( data );
            user.IsWatchingForChanges = watchForChanges;

            return user;
        }

        #endregion Public Methods

        #region Private Methods

        private void CacheUserPrincipal()
        {
            _userPrincipal = UserPrincipal.FindByIdentity( UserPrincipal.Current.Context, Name );
        }

        #endregion Private Methods

        #region Event Handlers

        private void Children_CollectionChanged( object sender, NotifyCollectionChangedEventArgs e )
        {
            if ( e.Action == NotifyCollectionChangedAction.Add )
            {
                foreach ( Record item in e.NewItems )
                {
                    P4Credential credential = item as P4Credential;

                    if ( credential != null )
                    {
                        credential.PropertyChanged += Credential_PropertyChanged;

                        if( credential.IsDefault )
                        {
                            Debug.Assert( DefaultCredential == null, $"User '{Name}' has more than 1 default credential set" );

                            DefaultCredential = credential;
                        }
                    }
                }
            }
        }

        private void Credential_PropertyChanged( object sender, PropertyChangedEventArgs e )
        {
            P4Credential credential = sender as P4Credential;

            if ( credential != null )
            {
                switch ( e.PropertyName )
                {
                    case "IsDefault":

                        if ( credential.IsDefault && credential != DefaultCredential )
                        {
                            if ( DefaultCredential != null )
                            {
                                DefaultCredential.IsDefault = false;
                            }

                            DefaultCredential = credential;
                        }

                        break;
                }
            }
        }

        #endregion Event Handlers
    }
}
